// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动！任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任！

using Admin.NET.Core.Service;
using Microsoft.AspNetCore.Http;
using Furion.DatabaseAccessor;
using Furion.FriendlyException;
using Mapster;
using SqlSugar;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using Admin.NET.Application.Entity;
using Admin.NET.Application.Service.InventoryQuery.Dto;
using Admin.NET.Core;
using System.Linq;
using Furion.DynamicApiController;

namespace Admin.NET.Application;

/// <summary>
/// 库存查询服务 🧩
/// </summary>
[ApiDescriptionSettings(ApplicationConst.GroupName, Order = 100)]
public partial class InventoryQueryService : IDynamicApiController, ITransient
{
    private readonly ISqlSugarClient _sqlSugarClient;
    private readonly SysDictDataService _sysDictDataService;

    public InventoryQueryService(ISqlSugarClient sqlSugarClient, SysDictDataService sysDictDataService)
    {
        _sqlSugarClient = sqlSugarClient;
        _sysDictDataService = sysDictDataService;
    }

    /// <summary>
    /// 分页查询库存信息 🔖
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("分页查询库存信息")]
    [ApiDescriptionSettings(Name = "Page"), HttpPost]
    public async Task<SqlSugarPagedList<InventoryQueryOutput>> Page(PageInventoryQueryInput input)
    {
        input.Keyword = input.Keyword?.Trim();

        // 多表联查：货品表、仓库表、库位表、货品类型表
        var query = _sqlSugarClient.Queryable<GoodsModel>()
            .LeftJoin<WarehouseModel>((g, w) => g.GoodsWareId == w.Id)
            .LeftJoin<WarePlaceModel>((g, w, wp) => w.Id == wp.Id)
            .LeftJoin<GoodsTypeModel>((g, w, wp, gt) => g.GoodsTypeId == gt.Id)
            .WhereIF(!string.IsNullOrWhiteSpace(input.Keyword), (g, w, wp, gt) =>
                g.GoodsCode.Contains(input.Keyword) ||
                g.GoodsName.Contains(input.Keyword) ||
                g.GoodsSpecs.Contains(input.Keyword))
            .WhereIF(!string.IsNullOrWhiteSpace(input.GoodsName), (g, w, wp, gt) =>
                g.GoodsName.Contains(input.GoodsName.Trim()))
            .WhereIF(!string.IsNullOrWhiteSpace(input.GoodsType), (g, w, wp, gt) =>
                g.GoodsTypeId.ToString() == input.GoodsType)
            .WhereIF(!string.IsNullOrWhiteSpace(input.WarehouseName), (g, w, wp, gt) =>
                w.WareName.Contains(input.WarehouseName.Trim()))
            .WhereIF(!string.IsNullOrWhiteSpace(input.Barcode), (g, w, wp, gt) =>
                g.GoodsCode.Contains(input.Barcode.Trim()))
            .WhereIF(input.ShowDisabled == false, (g, w, wp, gt) => g.GoodsType == true)
            .Select((g, w, wp, gt) => new InventoryQueryOutput
            {
                Id = g.Id,
                GoodsCode = g.GoodsCode,
                GoodsName = g.GoodsName,
                Status = g.GoodsType ? "启用" : "停用",
                GoodsType = gt.GoodsTypeName ?? g.GoodsTypeId.ToString(),
                Specs = g.GoodsSpecs,
                Unit = g.GoodsUnitId.ToString(), // 先使用ID，后续会通过字典服务获取名称
                Barcode = g.GoodsCode,
                WarehouseName = w.WareName,
                LocationName = wp.WarePlaceName,
                CurrentStock = 0, // 将在后续计算
                StockAmount = 0,
                PendingInbound = 0,
                PendingOutbound = 0,
                AvailableStock = 0,
                AvailableStockAmount = 0,
                BeginningStock = 0,
                EndingStock = 0,
                CreateTime = g.CreateTime,
                UpdateTime = g.UpdateTime ?? DateTime.MinValue
            });

        var result = await query.OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize);

        // 为每个货品计算库存数据
        foreach (var item in result.Items)
        {
            // 获取货品单价
            var goodsPrice = await _sqlSugarClient.Queryable<GoodsModel>()
                .Where(g => g.Id == item.Id)
                .Select(g => g.GoodsIntoMoney)
                .FirstAsync();

            // 计算入库数量
            var inboundQuantity = await _sqlSugarClient.Queryable<Sysinstockorder>()
                .Where(u => u.GoodsName.Contains(item.GoodsName))
                .WhereIF(!string.IsNullOrWhiteSpace(input.WarehouseName), u =>
                    u.WarehouseName.Contains(input.WarehouseName))
                .SumAsync(u => u.InQuantity);

            // 计算出库数量
            var outboundQuantity = await _sqlSugarClient.Queryable<Sysoutstockorder>()
                .Where(u => u.GoodsName.Contains(item.GoodsName))
                .WhereIF(!string.IsNullOrWhiteSpace(input.WarehouseName), u =>
                    u.WarehouseName.Contains(input.WarehouseName))
                .SumAsync(u => u.OutQuantity);

            // 计算待入库数量（采购订单）
            var pendingInbound = await _sqlSugarClient.Queryable<Syspurchaseorder>()
                .Where(u => u.GoodsName.Contains(item.GoodsName))
                .Where(u => u.DocumentStatus == DocumentStatusEnum.Completed.ToString())
                .SumAsync(u => u.ItemQuantity);

            // 计算待出库数量（销售订单）
            var pendingOutbound = await _sqlSugarClient.Queryable<Syssalesorder>()
                .Where(u => u.GoodsName.Contains(item.GoodsName))
                .Where(u => u.DocumentStatus == DocumentStatusEnum.Completed)
                .SumAsync(u => u.SalesQuantity);

            // 计算当前库存
            item.CurrentStock = inboundQuantity - outboundQuantity;
            item.StockAmount = item.CurrentStock * Convert.ToDecimal(goodsPrice ?? 0);

            // 待入库和待出库数量
            item.PendingInbound = pendingInbound;
            item.PendingOutbound = pendingOutbound;

            // 可用库存 = 当前库存 - 锁定库存（这里简化处理，假设没有锁定库存）
            item.AvailableStock = item.CurrentStock;
            item.AvailableStockAmount = item.AvailableStock * Convert.ToDecimal(goodsPrice ?? 0);

            // 期初库存 = 入库总量（假设期初为0，所有库存都来自入库）
            item.BeginningStock = inboundQuantity;

            // 期末库存 = 当前库存
            item.EndingStock = item.CurrentStock;
        }

        // 过滤零库存商品
        if (input.FilterZero)
        {
            result.Items = result.Items.Where(x => x.CurrentStock > 0).ToList();
            result.Total = result.Items.Count();
        }

        // 获取货品单位字典数据（使用与货品表管理相同的方式）
        var goodsUnitDict = await _sysDictDataService.GetDataList("GoodsEnumm");

        // 映射货品单位名称（完全按照货品表管理的逻辑）
        foreach (var item in result.Items)
        {
            if (!string.IsNullOrEmpty(item.Unit))
            {
                // 按照货品表管理的逻辑：优先匹配 value，然后匹配 id
                var unit = goodsUnitDict?.FirstOrDefault(u =>
                    u.Value == item.Unit || u.Id.ToString() == item.Unit);

                if (unit != null)
                {
                    // 按照货品表管理的逻辑：优先使用 label，如果没有则使用 name
                    item.Unit = !string.IsNullOrEmpty(unit.Label) ? unit.Label : unit.Name ?? item.Unit;
                }
            }
        }

        return result;
    }

    /// <summary>
    /// 获取库存统计信息 📊
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("获取库存统计信息")]
    [ApiDescriptionSettings(Name = "GetStats"), HttpPost]
    public async Task<InventoryStatsOutput> GetStats(GetInventoryStatsInput input)
    {
        // 当前库存统计 - 从入库和出库记录计算
        var inboundTotal = await _sqlSugarClient.Queryable<Sysinstockorder>()
            .WhereIF(!string.IsNullOrWhiteSpace(input.WarehouseName), u =>
                u.WarehouseName.Contains(input.WarehouseName))
            .WhereIF(input.DateRange?.Length == 2, u =>
                u.InDate >= input.DateRange[0] && u.InDate <= input.DateRange[1])
            .SumAsync(u => u.InQuantity);

        var outboundTotal = await _sqlSugarClient.Queryable<Sysoutstockorder>()
            .WhereIF(!string.IsNullOrWhiteSpace(input.WarehouseName), u =>
                u.WarehouseName.Contains(input.WarehouseName))
            .WhereIF(input.DateRange?.Length == 2, u =>
                u.OutDate >= input.DateRange[0] && u.OutDate <= input.DateRange[1])
            .SumAsync(u => u.OutQuantity);

        var currentQuantity = inboundTotal - outboundTotal;

        // 计算库存金额 - 从货品表获取单价
        var goodsWithPrice = await _sqlSugarClient.Queryable<GoodsModel>()
            .Where(g => g.GoodsIntoMoney.HasValue && g.GoodsIntoMoney > 0)
            .ToListAsync();

        var currentAmount = 0m;
        if (goodsWithPrice.Any())
        {
            var avgPrice = goodsWithPrice.Average(g => g.GoodsIntoMoney ?? 0);
            currentAmount = currentQuantity * Convert.ToDecimal(avgPrice);
        }

        // 入库统计
        var inboundQuery = _sqlSugarClient.Queryable<Sysinstockorder>()
            .WhereIF(!string.IsNullOrWhiteSpace(input.WarehouseName), u =>
                u.WarehouseName.Contains(input.WarehouseName))
            .WhereIF(input.DateRange?.Length == 2, u =>
                u.InDate >= input.DateRange[0] && u.InDate <= input.DateRange[1]);

        var inboundQuantity = await inboundQuery.SumAsync(u => u.InQuantity);

        // 出库统计
        var outboundQuery = _sqlSugarClient.Queryable<Sysoutstockorder>()
            .WhereIF(!string.IsNullOrWhiteSpace(input.WarehouseName), u =>
                u.WarehouseName.Contains(input.WarehouseName))
            .WhereIF(input.DateRange?.Length == 2, u =>
                u.OutDate >= input.DateRange[0] && u.OutDate <= input.DateRange[1]);

        var outboundQuantity = await outboundQuery.SumAsync(u => u.OutQuantity);

        // 待入库统计
        var pendingInboundQuery = _sqlSugarClient.Queryable<Syspurchaseorder>()
            .Where(u => u.DocumentStatus == DocumentStatusEnum.Completed.ToString());
        // Syspurchaseorder 无仓库名称字段，这里不按仓库过滤

        var pendingInbound = await pendingInboundQuery.SumAsync(u => u.ItemQuantity);

        // 待出库统计
        var pendingOutboundQuery = _sqlSugarClient.Queryable<Syssalesorder>()
            .Where(u => u.DocumentStatus == DocumentStatusEnum.Completed);
        // Syssalesorder 无仓库名称字段，这里不按仓库过滤

        var pendingOutbound = await pendingOutboundQuery.SumAsync(u => u.SalesQuantity);

        return new InventoryStatsOutput
        {
            CurrentQuantity = currentQuantity,
            CurrentAmount = currentAmount,
            InboundQuantity = inboundQuantity,
            OutboundQuantity = outboundQuantity,
            PendingInbound = pendingInbound,
            PendingOutbound = pendingOutbound
        };
    }

    /// <summary>
    /// 获取出入库流水 📋
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("获取出入库流水")]
    [ApiDescriptionSettings(Name = "GetStockFlow"), HttpPost]
    public async Task<SqlSugarPagedList<StockFlowOutput>> GetStockFlow(GetStockFlowInput input)
    {
        // 入库流水
        var inboundFlow = _sqlSugarClient.Queryable<Sysinstockorder>()
            .LeftJoin<GoodsModel>((si, g) => si.GoodsName.Contains(g.GoodsName))
            .WhereIF(!string.IsNullOrWhiteSpace(input.GoodsCode), (si, g) =>
                g.GoodsCode.Contains(input.GoodsCode))
            .WhereIF(!string.IsNullOrWhiteSpace(input.WarehouseName), (si, g) =>
                si.WarehouseName.Contains(input.WarehouseName))
            .WhereIF(!string.IsNullOrWhiteSpace(input.DocumentCode), (si, g) =>
                si.Code.Contains(input.DocumentCode))
            .WhereIF(!string.IsNullOrWhiteSpace(input.BusinessType) && input.BusinessType == "入库", (si, g) => true)
            .WhereIF(!string.IsNullOrWhiteSpace(input.FlowType), (si, g) =>
                input.FlowType == "进货入库" || input.FlowType == "调拨入库" || input.FlowType == "退货入库")
            .WhereIF(input.OperationDate.HasValue, (si, g) =>
                si.InDate.Date == input.OperationDate.Value.Date)
            .WhereIF(input.CreateDate.HasValue, (si, g) =>
                si.InDate.Date == input.CreateDate.Value.Date)
            .WhereIF(input.DateRange?.Length == 2, (si, g) =>
                si.InDate >= input.DateRange[0] && si.InDate <= input.DateRange[1])
            .Select((si, g) => new StockFlowOutput
            {
                Id = si.Id,
                DocumentCode = si.Code,
                BusinessType = "入库",
                FlowType = "进货入库", // 默认类型
                GoodsCode = g.GoodsCode,
                GoodsName = g.GoodsName,
                WarehouseName = si.WarehouseName,
                LocationName = "仓位一", // 默认值
                InboundQuantity = si.InQuantity,
                OutboundQuantity = 0,
                InboundAmount = si.InQuantity * Convert.ToDecimal(g.GoodsIntoMoney ?? 0),
                OutboundAmount = 0,
                OperationDate = si.InDate.ToString("yyyy-MM-dd"),
                Operator = si.AgentName,
                Creator = si.AgentName, // 制单人
                Department = "仓储部", // 默认部门
                CreateTime = si.InDate.ToString("yyyy-MM-dd HH:mm:ss"),
                Remark = si.Remark
            });

        // 出库流水
        var outboundFlow = _sqlSugarClient.Queryable<Sysoutstockorder>()
            .LeftJoin<GoodsModel>((so, g) => so.GoodsName.Contains(g.GoodsName))
            .WhereIF(!string.IsNullOrWhiteSpace(input.GoodsCode), (so, g) =>
                g.GoodsCode.Contains(input.GoodsCode))
            .WhereIF(!string.IsNullOrWhiteSpace(input.WarehouseName), (so, g) =>
                so.WarehouseName.Contains(input.WarehouseName))
            .WhereIF(!string.IsNullOrWhiteSpace(input.DocumentCode), (so, g) =>
                so.Code.Contains(input.DocumentCode))
            .WhereIF(!string.IsNullOrWhiteSpace(input.BusinessType) && input.BusinessType == "出库", (so, g) => true)
            .WhereIF(!string.IsNullOrWhiteSpace(input.FlowType), (so, g) =>
                input.FlowType == "销售出库" || input.FlowType == "调拨出库" || input.FlowType == "退货出库")
            .WhereIF(input.OperationDate.HasValue, (so, g) =>
                so.OutDate.Date == input.OperationDate.Value.Date)
            .WhereIF(input.CreateDate.HasValue, (so, g) =>
                so.OutDate.Date == input.CreateDate.Value.Date)
            .WhereIF(input.DateRange?.Length == 2, (so, g) =>
                so.OutDate >= input.DateRange[0] && so.OutDate <= input.DateRange[1])
            .Select((so, g) => new StockFlowOutput
            {
                Id = so.Id,
                DocumentCode = so.Code,
                BusinessType = "出库",
                FlowType = "销售出库", // 默认类型
                GoodsCode = g.GoodsCode,
                GoodsName = g.GoodsName,
                WarehouseName = so.WarehouseName,
                LocationName = "仓位一", // 默认值
                InboundQuantity = 0,
                OutboundQuantity = so.OutQuantity,
                InboundAmount = 0,
                OutboundAmount = so.OutQuantity * Convert.ToDecimal(g.GoodsOutMoney ?? 0),
                OperationDate = so.OutDate.ToString("yyyy-MM-dd"),
                Operator = so.ContactPerson,
                Creator = so.ContactPerson, // 制单人
                Department = "仓储部", // 默认部门
                CreateTime = so.OutDate.ToString("yyyy-MM-dd HH:mm:ss"),
                Remark = so.Remark
            });

        // 分别获取入库和出库流水
        var inboundList = await inboundFlow.ToListAsync();
        var outboundList = await outboundFlow.ToListAsync();

        // 合并流水并按时间排序
        var allFlow = inboundList.Concat(outboundList)
            .OrderByDescending(x => x.CreateTime)
            .Skip((input.Page - 1) * input.PageSize)
            .Take(input.PageSize)
            .ToList();

        return new SqlSugarPagedList<StockFlowOutput>
        {
            Items = allFlow,
            Total = inboundList.Count + outboundList.Count,
            Page = input.Page,
            PageSize = input.PageSize
        };
    }

    /// <summary>
    /// 导出出入库流水数据 📊
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("导出出入库流水数据")]
    [ApiDescriptionSettings(Name = "ExportStockFlow"), HttpPost]
    public async Task<byte[]> ExportStockFlow(GetStockFlowInput input)
    {
        // 获取所有流水数据（不分页）
        var inboundFlow = _sqlSugarClient.Queryable<Sysinstockorder>()
            .LeftJoin<GoodsModel>((si, g) => si.GoodsName.Contains(g.GoodsName))
            .WhereIF(!string.IsNullOrWhiteSpace(input.GoodsCode), (si, g) =>
                g.GoodsCode.Contains(input.GoodsCode))
            .WhereIF(!string.IsNullOrWhiteSpace(input.WarehouseName), (si, g) =>
                si.WarehouseName.Contains(input.WarehouseName))
            .WhereIF(!string.IsNullOrWhiteSpace(input.DocumentCode), (si, g) =>
                si.Code.Contains(input.DocumentCode))
            .WhereIF(!string.IsNullOrWhiteSpace(input.BusinessType) && input.BusinessType == "入库", (si, g) => true)
            .WhereIF(!string.IsNullOrWhiteSpace(input.FlowType), (si, g) =>
                input.FlowType == "进货入库" || input.FlowType == "调拨入库" || input.FlowType == "退货入库")
            .WhereIF(input.OperationDate.HasValue, (si, g) =>
                si.InDate.Date == input.OperationDate.Value.Date)
            .WhereIF(input.CreateDate.HasValue, (si, g) =>
                si.InDate.Date == input.CreateDate.Value.Date)
            .WhereIF(input.DateRange?.Length == 2, (si, g) =>
                si.InDate >= input.DateRange[0] && si.InDate <= input.DateRange[1])
            .Select((si, g) => new StockFlowOutput
            {
                Id = si.Id,
                DocumentCode = si.Code,
                BusinessType = "入库",
                FlowType = "进货入库",
                GoodsCode = g.GoodsCode,
                GoodsName = g.GoodsName,
                WarehouseName = si.WarehouseName,
                LocationName = "仓位一",
                InboundQuantity = si.InQuantity,
                OutboundQuantity = 0,
                InboundAmount = si.InQuantity * Convert.ToDecimal(g.GoodsIntoMoney ?? 0),
                OutboundAmount = 0,
                OperationDate = si.InDate.ToString("yyyy-MM-dd"),
                Operator = si.AgentName,
                Creator = si.AgentName,
                Department = "仓储部",
                CreateTime = si.InDate.ToString("yyyy-MM-dd HH:mm:ss"),
                Remark = si.Remark
            });

        var outboundFlow = _sqlSugarClient.Queryable<Sysoutstockorder>()
            .LeftJoin<GoodsModel>((so, g) => so.GoodsName.Contains(g.GoodsName))
            .WhereIF(!string.IsNullOrWhiteSpace(input.GoodsCode), (so, g) =>
                g.GoodsCode.Contains(input.GoodsCode))
            .WhereIF(!string.IsNullOrWhiteSpace(input.WarehouseName), (so, g) =>
                so.WarehouseName.Contains(input.WarehouseName))
            .WhereIF(!string.IsNullOrWhiteSpace(input.DocumentCode), (so, g) =>
                so.Code.Contains(input.DocumentCode))
            .WhereIF(!string.IsNullOrWhiteSpace(input.BusinessType) && input.BusinessType == "出库", (so, g) => true)
            .WhereIF(!string.IsNullOrWhiteSpace(input.FlowType), (so, g) =>
                input.FlowType == "销售出库" || input.FlowType == "调拨出库" || input.FlowType == "退货出库")
            .WhereIF(input.OperationDate.HasValue, (so, g) =>
                so.OutDate.Date == input.OperationDate.Value.Date)
            .WhereIF(input.CreateDate.HasValue, (so, g) =>
                so.OutDate.Date == input.CreateDate.Value.Date)
            .WhereIF(input.DateRange?.Length == 2, (so, g) =>
                so.OutDate >= input.DateRange[0] && so.OutDate <= input.DateRange[1])
            .Select((so, g) => new StockFlowOutput
            {
                Id = so.Id,
                DocumentCode = so.Code,
                BusinessType = "出库",
                FlowType = "销售出库",
                GoodsCode = g.GoodsCode,
                GoodsName = g.GoodsName,
                WarehouseName = so.WarehouseName,
                LocationName = "仓位一",
                InboundQuantity = 0,
                OutboundQuantity = so.OutQuantity,
                InboundAmount = 0,
                OutboundAmount = so.OutQuantity * Convert.ToDecimal(g.GoodsOutMoney ?? 0),
                OperationDate = so.OutDate.ToString("yyyy-MM-dd"),
                Operator = so.ContactPerson,
                Creator = so.ContactPerson,
                Department = "仓储部",
                CreateTime = so.OutDate.ToString("yyyy-MM-dd HH:mm:ss"),
                Remark = so.Remark
            });

        var inboundList = await inboundFlow.ToListAsync();
        var outboundList = await outboundFlow.ToListAsync();
        var allFlow = inboundList.Concat(outboundList)
            .OrderByDescending(x => x.CreateTime)
            .ToList();

        // 这里应该使用 Excel 导出库，暂时返回空字节数组
        // 实际项目中应该使用 EPPlus 或 ClosedXML 等库来生成 Excel 文件
        return new byte[0];
    }

    /// <summary>
    /// 获取库存分布 📍
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("获取库存分布")]
    [ApiDescriptionSettings(Name = "GetStockDistribution"), HttpPost]
    public async Task<SqlSugarPagedList<StockDistributionOutput>> GetStockDistribution(GetStockDistributionInput input)
    {
        // 从货品表获取基本信息
        var query = _sqlSugarClient.Queryable<GoodsModel>()
            .LeftJoin<WarehouseModel>((g, w) => g.GoodsWareId == w.Id)
            .LeftJoin<WarePlaceModel>((g, w, wp) => w.Id == wp.Id)
            .WhereIF(!string.IsNullOrWhiteSpace(input.GoodsCode), (g, w, wp) =>
                g.GoodsCode.Contains(input.GoodsCode))
            .WhereIF(!string.IsNullOrWhiteSpace(input.WarehouseName), (g, w, wp) =>
                w.WareName.Contains(input.WarehouseName))
            .Select((g, w, wp) => new StockDistributionOutput
            {
                Id = g.Id,
                GoodsCode = g.GoodsCode,
                GoodsName = g.GoodsName,
                WarehouseName = w.WareName,
                LocationName = wp.WarePlaceName,
                StockQuantity = 0, // 将在后续计算
                StockAmount = 0,
                AvailableQuantity = 0,
                LockedQuantity = 0
            });

        // 获取基础数据
        var baseData = await query.ToListAsync();

        // 为每个货品计算库存分布数据
        foreach (var item in baseData)
        {
            // 获取货品单价
            var goodsPrice = await _sqlSugarClient.Queryable<GoodsModel>()
                .Where(g => g.Id == item.Id)
                .Select(g => g.GoodsIntoMoney)
                .FirstAsync();

            // 计算入库数量
            var inboundQuantity = await _sqlSugarClient.Queryable<Sysinstockorder>()
                .Where(u => u.GoodsName.Contains(item.GoodsName))
                .WhereIF(!string.IsNullOrWhiteSpace(input.WarehouseName), u =>
                    u.WarehouseName.Contains(input.WarehouseName))
                .SumAsync(u => u.InQuantity);

            // 计算出库数量
            var outboundQuantity = await _sqlSugarClient.Queryable<Sysoutstockorder>()
                .Where(u => u.GoodsName.Contains(item.GoodsName))
                .WhereIF(!string.IsNullOrWhiteSpace(input.WarehouseName), u =>
                    u.WarehouseName.Contains(input.WarehouseName))
                .SumAsync(u => u.OutQuantity);

            // 计算库存分布数据
            item.StockQuantity = inboundQuantity - outboundQuantity;
            item.StockAmount = item.StockQuantity * Convert.ToDecimal(goodsPrice ?? 0);
            item.AvailableQuantity = item.StockQuantity; // 简化处理，假设没有锁定库存
            item.LockedQuantity = 0; // 简化处理，假设没有锁定库存
        }

        // 手动分页
        var total = baseData.Count;
        var pagedData = baseData
            .Skip((input.Page - 1) * input.PageSize)
            .Take(input.PageSize)
            .ToList();

        return new SqlSugarPagedList<StockDistributionOutput>
        {
            Items = pagedData,
            Total = total,
            Page = input.Page,
            PageSize = input.PageSize
        };
    }

    /// <summary>
    /// 获取单位列表
    /// </summary>
    /// <returns></returns>
    [DisplayName("获取单位列表")]
    [ApiDescriptionSettings(Name = "GetUnits"), HttpGet]
    public async Task<List<object>> GetUnits()
    {
        try
        {
            // 从字典数据中获取货品单位枚举
            var units = await _sysDictDataService.GetDataList("GoodsEnumm");

            if (units != null && units.Any())
            {
                return units.Select(u => new
                {
                    id = u.Id,
                    value = u.Value,
                    label = !string.IsNullOrEmpty(u.Label) ? u.Label : u.Name,
                    name = u.Name
                }).Cast<object>().ToList();
            }
            else
            {
                // 如果字典中没有数据，返回默认单位
                return new List<object>
                {
                    new { id = 1, value = "1", label = "台", name = "台" },
                    new { id = 2, value = "2", label = "个", name = "个" },
                    new { id = 3, value = "3", label = "件", name = "件" },
                    new { id = 4, value = "4", label = "箱", name = "箱" },
                    new { id = 5, value = "5", label = "包", name = "包" },
                    new { id = 6, value = "6", label = "瓶", name = "瓶" },
                    new { id = 7, value = "7", label = "盒", name = "盒" },
                    new { id = 8, value = "8", label = "套", name = "套" },
                    new { id = 9, value = "9", label = "袋", name = "袋" },
                    new { id = 10, value = "10", label = "公斤", name = "公斤" }
                };
            }
        }
        catch (Exception ex)
        {
            throw Oops.Oh($"获取单位列表失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 获取仓库列表
    /// </summary>
    /// <returns></returns>
    [DisplayName("获取仓库列表")]
    [ApiDescriptionSettings(Name = "GetWarehouses"), HttpGet]
    public async Task<List<object>> GetWarehouses()
    {
        try
        {
            var warehouses = await _sqlSugarClient.Queryable<WarehouseModel>()
                .Where(w => w.WareType == true) // 只获取启用的仓库
                .Select(w => new
                {
                    id = w.Id,
                    wareName = w.WareName,
                    wareCode = w.WareCode,
                    name = w.WareName
                })
                .ToListAsync();

            return warehouses.Cast<object>().ToList();
        }
        catch (Exception ex)
        {
            throw Oops.Oh($"获取仓库列表失败: {ex.Message}");
        }
    }
}
